# _*_coding:utf-8_*_
__author__ = 'gerry'

import numpy as np
from scipy import linalg
import numpy.random as np_random

def main():
    print("使用普通的一维数组生成Numpy的一维数组")
    data = [6, 7.5, 8, 0, 1]
    arr = np.array(data)
    print(arr)
    print "打印元素类型"
    print(arr.dtype)

    print("--------------------------")
    data1 = [[1, 2, 3, 4], [5, 6, 7, 8]]
    arr1 = np.array(data1)
    print(arr1)
    print("打印数组维数")
    print(arr1.shape)

    print("--------------------------")
    print("使用zeros/empty")
    print(np.zeros(10))  # 生成包含10个0的一维数组
    print(np.zeros((3, 6)))  # 生成3*6的二维数组
    print(np.empty((2, 3, 2)))  # 生成2*3*2的三维数组，所有元素未初始化

    print("--------------------------")
    print("使用arange生成连续元素")
    print(np.arange(15))  # [0,1,2...14]

def data_type():
    print("生成数组的数据类型")
    arr = np.array([1,2,3],dtype=np.float64)
    print(arr.dtype)
    arr = np.array([1,2,3],dtype=np.int32)
    print(arr.dtype)

    print("--------------------------")
    print("使用astype复制数组并转换问数据类型")
    int_arr = np.array([1,2,3,4,5])
    float_arr = int_arr.astype(np.float)
    print(int_arr.dtype)
    print(float_arr.dtype)

    print("--------------------------")
    print("使用astype将float转换为int时小数部分被舍弃")
    float_arr = np.array([3.7,-1.2,-2.6,0.5,12.9,10.1])
    int_arr = float_arr.astype(dtype=np.int)
    print(int_arr)

    print("--------------------------")
    print("使用astype把字符串转换为数组，如果失败经抛出异常")
    str_arr = np.array(['1.25','-9.6','42'],dtype=np.string_)
    float_arr = str_arr.astype(dtype=np.float)
    print(float_arr)

    print("--------------------------")
    int_arr = np.arange(10)
    float_arr = np.array([0.23,0.270,0.357,0.44,0.5],dtype=np.float64)
    print(int_arr.astype(float_arr.dtype))
    print int_arr[0],int_arr[1] #astype做了复制，数组本身不会发生变化


def array_cal():

    #数组的乘法和减法，对应元素的乘法和减法
    arr = np.array([[1,2,3],[4,5,6]])
    print(arr*arr)
    print(arr-arr)
    print("--------------------------")
    #标量操作作用在数组的每一个元素上
    arr = np.array([[1.0,2.0,3.0],[4.0,5.0,6.0]])
    print(1/arr)
    print(arr**5) #开根号

def array_slice():
    #通过索引访问二维数组某一行或者某个元素
    arr = np.array([[1,2,3],[4,5,6],[7,8,9]])
    print(arr[2])
    print(arr[0][2])
    print(arr[0,2]) #普通数组不能用

    print("--------------------------")
    #对更高维数组的访问和操作
    arr = np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]])
    print(arr[0]) #结果是个二维数组
    print(arr[1,0]) #结果是个二维数组
    old_values = arr[0].copy() #复制arr[0]的值
    print(arr)
    arr[0] = old_values#把原来的数组放回去
    print(arr)
    print("--------------------------")

    print("使用切片和操作数组")
    arr = np.array([1,2,3,4,5,6,7,8,9,10])
    print(arr[1:6]) #打印元素arr[1]到arr[5]
    print("--------------------------")
    arr = np.array([[1,2,3],[4,5,6],[7,8,9]])
    print(arr[:2])#打印第1,2行
    print("--------------------------")
    print(arr[:2,1:])#打印第1,2行，第2,3列
    print("--------------------------")
    print(arr[:,:1])#打印第一列的所有元素
    print("--------------------------")
    arr[:2,1:] = 0#第1，2行，第3,4列的元素设置为0
    print("--------------------------")
    print(arr)

def boolean_index():

    print("使用布尔数组作为索引")
    name_arr = np.array(['Bob','Jpe','Will','Bob','Will','Joe','Joe'])
    print("随机7*4数组")
    rnd_arr = np_random.randn(7,4)#随机7*4数组
    print(rnd_arr)
    print("返回布尔数组，元素等于'Bob'为true,否则为False")
    print(name_arr=='Bob') #返回布尔数组，元素等于'Bob'为true,否则为False
    print("利用布尔数组选择行")
    print(rnd_arr[name_arr=='Bob'])#利用布尔数组选择行
    print("增加限制打印列的范围")
    print(rnd_arr[name_arr=='Bob',:2])#增加限制打印列的范围
    print("取反")
    print(rnd_arr[-(name_arr=='Bob')])
    print("逻辑运算混合结果")
    mask_arr = (name_arr=='Bob')|(name_arr=='Will')#逻辑运算混合结果
    print(rnd_arr[mask_arr])
    rnd_arr[name_arr!='Joe'] = 7 #先布尔数组选择行，然后把每行的元素设置为7
    print("先布尔数组选择行，然后把每行的元素设置为7")
    print(rnd_arr)


def fancy_Index():
    #使用整数数组作为索引
    arr = np.empty((8,4))
    for i in range(8):
        arr[i] = i
    print(arr)
    print("打印arr[4],arr[3],arr[0],arr[6]")
    print(arr[[4,3,0,6]])
    print("打印arr[3]、arr[5]arr[-7]")
    print(arr[[-3,-5,-7]])
    arr = np.arange(32).reshape((8,4)) #通过reshape变成二维数组
    print(arr)
    print("打印arr[1, 0]、arr[5, 3]，arr[7, 1]和arr[2, 2])")
    print(arr[[1,5,7,2],[0,3,1,2]]) # 打印arr[1, 0]、arr[5, 3]，arr[7, 1]和arr[2, 2]
    print("1572行的0312列")
    print(arr[[1,5,6,4]][:,[1,3,0,2]])

def transport_array():
    print("转置矩阵")
    arr = np.arange(15).reshape(3,5)
    print(arr)
    print(arr.T)

    print("转置矩阵做点积")
    arr = np_random.randn(6,3)
    print(np.dot(arr.T,arr))
    print("高维矩阵转换")
    arr = np.arange(16).reshape((2,2,4))
    print(arr)

    '''
    详细解释：
    arr数组的内容为
    - a[0][0] = [0, 1, 2, 3]
    - a[0][1] = [4, 5, 6, 7]
    - a[1][0] = [8, 9, 10, 11]
    - a[1][1] = [12, 13, 14, 15]
    transpose的参数为坐标，正常顺序为(0, 1, 2, ... , n - 1)，
    现在传入的为(1, 0, 2)代表a[x][y][z] = a[y][x][z]，第0个和第1个坐标互换。
    - a'[0][0] = a[0][0] = [0, 1, 2, 3]
    - a'[0][1] = a[1][0] = [8, 9, 10, 11]
    - a'[1][0] = a[0][1] = [4, 5, 6, 7]
    - a'[1][1] = a[1][1] = [12, 13, 14, 15]
    '''
    print(arr.transpose((1,0,2)))
    print(arr.swapaxes(1,2)) # 直接交换第1和第2个坐标

def zip_where():
    '''
    关于zip函数的一个解释，zip可以接受任意多参数，然后组合成一个tuple列表
    zip([1,2,3],[4,5,6],[7,8,9])
    返回结果：[(1,4,7),(2,5,8),(3,6,9)]
    '''
    print('通过真值表选择元素')
    x_arr = np.array([1.1,1.2,1.3,1.4,1.5])
    y_arr = np.array([2.1,2.2,2.3,2.4,2.5])
    cond = np.array([True,False,True,True,False])
    result = [(x if c else y) for x,y,c in zip(x_arr,y_arr,cond)]
    print(result)
    print(np.where(cond,x_arr,y_arr))
    print()
    print('更多where的例子')
    arr = np_random.randn(4,4)
    print(arr)
    print(np.where(arr>0,2,2))
    print(np.where(arr>0,2,arr))
    print()

    print('where嵌套')
    cond_1 = np.array([True,False,True,True,False])
    cond_2 = np.array([False,True,False,True,False])
    result = []
    for i in xrange(len(cond)):
        if cond_1[i] and cond_2[i]:
            result.append(0)
        elif cond_1[i]:
            result.append(1)
        elif cond_2[i]:
            result.append(2)
        else:
            result.append(3)
    print(result)
    result = np.where(cond_1&cond_2,0,\
                      np.where(cond_1,1,np.where(cond_2,2,3)))
    print(result)








if __name__ == '__main__':
    #main()
    #data_type()
    #array_cal()
    #array_slice()
    #boolean_index()
    #fancy_Index()
    #transport_array()
    zip_where()